//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.IO.Packaging;
using System.Windows.Media;
using System.Xml;
using OpenLS.Core;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;
using OpenLS.Spreadsheet.Internals;
using OpenLS.Spreadsheet.Pivot;
using OpenLS.Spreadsheet.Serialization;

namespace OpenLS.Spreadsheet
{
    internal class ObjectLookup<T>
    {
    }

    ///<summary>
    /// Contains style information for a workbook. In general, you should not use this class directly. Instead, you should set properties on cells and ranges.
    ///</summary>
    public sealed class StyleSheet : IOfficeXmlSerializable
    {
        private const string xmlName = "styleSheet";
        private readonly List<Color> _indexedColors = new List<Color>();
        private readonly Dictionary<int, Format> _numberFormats = new Dictionary<int, Format>();
        private Font _defaultFont;
        private Collections.HashSet<FormattingRecord> _formattingRecords = new Collections.HashSet<FormattingRecord>();
        private HashList<CellStyle> _styles = new HashList<CellStyle>();
        private List<TableStyle> _tableStyles = new List<TableStyle>();
        private List<Color> _themeColors;
        private readonly Workbook _workbook;
#if DEBUG
        private int tag;
#endif
        private FormattingRecord _defaultStyleRecord;

        internal FormattingRecord DefaultStyleRecord
        {
            get { return _defaultStyleRecord; }
        }

        public StyleSheet(Workbook workbook) : this()
        {
            _workbook = workbook;
        }

        public StyleSheet()
        {
            Initialize();
        }

        private void Initialize()
        {
            _formattingRecords = new Collections.HashSet<FormattingRecord>();
            bool first = true;
            foreach (CellFormattingRecord r in getDefaultStyleRecords())
            {
                if (first)
                {
                    _defaultStyleRecord = r;
                }
                _formattingRecords.Add(r);
            }
        }

        private List<CellStyle> _builtInStyles;

        [Obsolete("Use Workbook.BuiltInStyles instead")]
        public List<CellStyle> BuiltInStyles
        {
            get { return new List<CellStyle>(BuiltInStylesNew); }
        }

        internal IEnumerable<CellStyle> BuiltInStylesNew
        {
            get
            {
                if (_builtInStyles == null)
                {
                    _builtInStyles = new List<CellStyle>(GetBuiltInStyles());
                }
                return _builtInStyles;
            }
        }

        private IEnumerable<CellStyle> GetBuiltInStyles()
        {
            var sh = new StyleSheet(_workbook);
            string stylesString = StyleResources.Styles;
            using (XmlReader reader = new XmlTextReader(new StringReader(stylesString)))
            {
                var ctx = new ReadContext(reader, null, SpreadsheetConstants.SpreadsheetNamespaceUri);
                _workbook.AddToReadContext(ctx);
                sh.readColors(ctx);
            }
            using (XmlReader reader = new XmlTextReader(new StringReader(stylesString)))
            {
                var ctx = new ReadContext(reader, null, SpreadsheetConstants.SpreadsheetNamespaceUri);
                _workbook.AddToReadContext(ctx);
                ctx.AddData(new StyleRecordManager());
                sh.readXml(ctx);
                foreach (CellStyle cellStyle in sh.Styles)
                {
                    yield return cellStyle;
                }
            }
        }

        private Collections.HashSet<FormattingRecord> FormattingRecords
        {
            get { return _formattingRecords; }
            set { _formattingRecords = value; }
        }

        internal IEnumerable<FormattingRecord> GetStyleRecords()
        {
            string minorfontName = "Arial";
            if (this._workbook.Theme != null && _workbook.Theme.FontScheme != null)
                minorfontName = _workbook.Theme.FontScheme.MinorFont.Latin.Source;
            var firstRecords = new List<FormattingRecord>();
            var ff = getDefaultStyleRecords();
            foreach (CellFormattingRecord item in Enumerable.Select(ff, LookupNewCellFormattingRecord))
                firstRecords.Add(item);
            IEnumerable<FormattingRecord> allRecords = Enumerable.Union(firstRecords, FormattingRecords);
            IEnumerable<FormattingRecord> result = Enumerable.Distinct(allRecords);
            return result;
        }


        internal HashList<CellStyle> Styles
        {
            get { return _styles; }
            set { _styles = value; }
        }


        public List<Color> IndexedColors
        {
            get { return _indexedColors; }
        }

        public List<Color> ThemeColors
        {
            get { return _themeColors; }
        }

        public List<TableStyle> TableStyles
        {
            get { return _tableStyles; }
            set { _tableStyles = value; }
        }

        private ExtensionElement Extension { get; set; }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read(xmlName))
            {
                c.PassAttributes();
                _numberFormats.Clear();
                Initialize();
                if (c.ReaderLocalName == "numFmts")
                {
                    using (ReadContext cc = c.Read("numFmts"))
                    {
                        while (cc.ReaderLocalName == "numFmt")
                        {
                            var format = cc.ReadElement<InternalNumberFormat>();
                            _numberFormats.Add(format.Id, Format.Parse(format.Code));
                        }
                    }
                }
                var fonts = new List<Font>();
                if (c.ReaderLocalName == "fonts")
                    using (ReadContext cFonts = c.Read("fonts"))
                    {
                        while (cFonts.ReaderLocalName == "font")
                        {
                            var font = new Font();
                            font.ReadXml(cFonts);
                            fonts.Add(font);
                        }
                    }
                if (fonts.Count > 0)
                    _defaultFont = fonts[0];
                var fills = new List<Fill>();
                if (c.ReaderLocalName == "fills")
                {
                    using (ReadContext fillsC = context.Read("fills"))
                    {
                        while (fillsC.ReaderLocalName == "fill")
                        {
                            fills.Add(Fill.ReadFill(fillsC));
                        }
                    }
                }
                var borders = new List<Borders>();
                if (c.ReaderLocalName == "borders")
                {
                    using (ReadContext bordersC = c.Read("borders"))
                    {
                        while (bordersC.ReaderLocalName == "border")
                        {
                            borders.Add(bordersC.ReadElement<Borders>());
                        }
                    }
                }
                var cellStyleRecords = new List<StyleFormattingRecord>();
                c.AddData(cellStyleRecords);
                if (c.ReaderLocalName == "cellStyleXfs")
                {
                    using (ReadContext ccc = context.Read("cellStyleXfs"))
                    {
                        ccc.AddData(this);
                        ccc.AddData(fonts);
                        ccc.AddData(borders);
                        ccc.AddData(fills);
                        while (ccc.ReaderLocalName == "xf")
                        {
                            var r = new StyleFormattingRecord();
                            r.ReadXml(ccc);
                            cellStyleRecords.Add(r);
                        }
                    }
                }
                _formattingRecords = new Collections.HashSet<FormattingRecord>();
                c.AddData(this);
                c.AddData(fonts);
                c.AddData(fills);
                c.AddData(borders);
                if (c.ReaderLocalName == "cellXfs")
                {
                    var manager = context.GetData<StyleRecordManager>();
                    Contract.Assert((manager != null));
                    using (ReadContext ccc = c.Read("cellXfs"))
                    {
                        Contract.Assert(c.GetData<StyleSheet>() != null);
                        Contract.Assert(ccc.GetData<StyleSheet>() != null);
                        while (ccc.ReaderLocalName == "xf")
                        {
                            var r = new CellFormattingRecord();
#if DEBUG
                            tag++;
                            r.tag = tag;
#endif

                            if (ccc.GetOptionalString("xfId") != null)
                                r.SetParent(cellStyleRecords[ccc.GetInteger("xfId")]);
                            r.ReadXml(c);
#if DEBUG
                            r.tag = _formattingRecords.Count;
#endif
                            bool b = _formattingRecords.TryAdd(r);
                            if (!b)
                            {
                                var oldOne = (CellFormattingRecord) _formattingRecords[(r)];
                                Contract.Assert(oldOne != r);
                                r = r;
                                manager.Add(oldOne);
                            }
                            else
                                manager.Add(r);
                            //\\Contract.Assert(b);
                        }
                    }
                }
                if (c.ReaderLocalName == "cellStyles")
                {
                    using (ReadContext ccc = c.Read("cellStyles"))
                    {
                        while (ccc.ReaderLocalName == "cellStyle")
                        {
                            var style = ccc.ReadElement<CellStyle>();
                            Styles.Add(style);
                        }
                    }
                }
                List<DifferentialStyleRecord> dxfs = c.ReadOptionalListElement<DifferentialStyleRecord>("dxfs", "dxf");
                // c.AddData(dxfs);
//\\                c.EatForNow("dxfs");
                var rr = c.GetData<DifferentialStyleRecordResolver>();
                if (rr == null)
                    rr = new DifferentialStyleRecordResolver(0);
                rr.Initialize(dxfs);
                //\\context.AddData(new DifferentialStyleRecordResolver(dxfs, 0));
                _tableStyles = c.ReadOptionalListElement<TableStyle>("tableStyles", "tableStyle");
                if (c.ReaderLocalName == "colors")
                {
                    using (ReadContext ccc = c.Read("colors"))
                    {
                        _themeColors = new List<Color>();
                        if (ccc.ReaderLocalName == "themeColors")
                        {
                            using (ReadContext cThemeColors = ccc.Read("themeColors"))
                            {
                                while (cThemeColors.ReaderLocalName == "rgbColor")
                                {
                                    using (ReadContext ccccc = cThemeColors.Read("rgbColor"))
                                    {
                                        _themeColors.Add(
                                            (Color) ColorConverter.ConvertFromString(@"#" + ccccc.GetString("rgb")));
                                    }
                                }
                            }
                        }
                        _indexedColors.Clear();
                        if (ccc.ReaderLocalName == "indexedColors")
                        {
                            using (ReadContext cIndexColors = ccc.Read("indexedColors"))
                            {
                                while (cIndexColors.ReaderLocalName == "rgbColor")
                                {
                                    using (ReadContext ccccc = cIndexColors.Read("rgbColor"))
                                    {
                                        IndexedColors.Add(
                                            (Color) ColorConverter.ConvertFromString(@"#" + ccccc.GetString("rgb")));
                                    }
                                }
                            }
                        }
                        ccc.EatForNow("mruColors");
                    }
                }
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            int i = 0;
            var allStyleRecords = new List<FormattingRecord>(GetStyleRecords());
            List<StyleFormattingRecord> parentStyles =
                Enumerable.ToList(
                    Enumerable.Distinct(Enumerable.Where(Enumerable.Select(allStyleRecords, r => r.Parent),
                                                         r2 => r2 != null)));
            if (parentStyles.Count > 0)
            {
                var first = Enumerable.First(BuiltInStylesNew).Record;
                if (!parentStyles.Contains(first))
                    parentStyles.Insert(0, first);
            }
            List<FormattingRecord> allStyleRecordsAndParentStyleRecords =
                Enumerable.ToList(Enumerable.Union(allStyleRecords, Enumerable.OfType<FormattingRecord>(parentStyles)));
            foreach (FormattingRecord r in allStyleRecords)
            {
                r.Id = i++;
            }
            using (WriteContext c = context.Write(xmlName))
            {
                var fonts = new Dictionary<Font, int>();
                var fills = new HashList<Fill>();
                var formats = new Dictionary<string, int>();

                foreach (Fill f in getDefaultFills())
                    fills.Add(f);
                var borders = new Dictionary<Borders, int> {{new Borders(), 0}};
                FontFamily defaultFontFamily;
                defaultFontFamily = _workbook.Theme != null && _workbook.Theme.FontScheme != null
                                        ? _workbook.Theme.FontScheme.MinorFont.Latin
                                        : new FontFamily("Arial");
                if (_defaultFont == null)
                    _defaultFont = new Font(defaultFontFamily, f =>
                                                                   {
                                                                       f.Foreground =
                                                                           new ThemeColor(ColorSchemeIndex.Dark1, null);
                                                                       f.Scheme = FontSchemeType.Minor;
                                                                   });
                Contract.Assert(fonts.Count == 0);
                fonts.Add(_defaultFont, fonts.Count);
                if (_formattingRecords == null)
                {
                    // Contract.Assert(false);
                    Initialize();
                }
                foreach (FormattingRecord r in allStyleRecordsAndParentStyleRecords)
                {
                    if (r.Font != null)
                        r.Font.PreWriteXml(context);
                }
                foreach (FormattingRecord r in allStyleRecordsAndParentStyleRecords)
                {
                    if (r.RawFormat != null && !formats.ContainsKey(r.RawFormat.Code))
                    {
                        if (StandardFormats.GetFormatId(r.RawFormat.Code) == null)
                            formats.Add(r.RawFormat.Code, formats.Count + 170); //\\hard coded
                    }
                    if (r.RawFont != null && !fonts.ContainsKey(r.RawFont))
                        fonts.Add(r.Font, fonts.Count);
                    if (r.RawFont != null)
                    {
                        object dummy = fonts[r.Font];
                    }
                    if (r.RawBackground != null && !fills.Contains(r.RawBackground))
                        fills.Add(r.RawBackground);
                    if (r.RawBorders != null && !borders.ContainsKey(r.RawBorders))
                        borders.Add(r.RawBorders, borders.Count);
                }
                using (WriteContext numFmtE = c.Write("numFmts"))
                {
                    numFmtE.SetInteger("count", formats.Count);
                    foreach (var pair in formats)
                    {
                        var fmt = new InternalNumberFormat(pair.Key, pair.Value);
                        numFmtE.WriteElement(fmt);
                    }
                }
                using (WriteContext fontsE = c.Write("fonts"))
                {
                    fontsE.SetInteger("count", fonts.Count);
                    var pairs = new List<KeyValuePair<Font, int>>(fonts);
                    pairs.Sort(compareKeys);
                    foreach (var pair in pairs)
                        context.WriteElement(pair.Key);
                }
                using (WriteContext fillsE = c.Write("fills"))
                {
                    fillsE.SetInteger("count", fills.Count);
                    int id = 0;
                    foreach (Fill f in fills)
                    {
                        f.Id = id++;
                        f.WriteXmlCore(fillsE);
                    }
                }
                using (WriteContext borderE = c.Write("borders"))
                {
                    borderE.SetInteger("count", borders.Count);
                    foreach (Borders f in borders.Keys)
                        borderE.WriteElement(f);
                }
                var styleStyleRecords = new Dictionary<FormattingRecord, int>();
                context.SetData(styleStyleRecords.GetType(), styleStyleRecords);
                if (parentStyles.Count > 0)
                {
                    using (WriteContext styleStyleXps = context.Write("cellStyleXfs"))
                    {
                        int count = 0;
                        styleStyleXps.SetInteger("count", parentStyles.Count);
                        styleStyleXps.SetData(fonts.GetType(), fonts);
                        styleStyleXps.SetData(formats.GetType(), formats);
                        styleStyleXps.SetData(fills.GetType(), fills);
                        styleStyleXps.SetData(borders.GetType(), borders);
                        foreach (FormattingRecord r in parentStyles)
                        {
                            styleStyleXps.WriteElement(r);
                            styleStyleRecords.Add(r, count++);
                        }
                    }
                }
                using (WriteContext cellXfsE = context.Write("cellXfs"))
                {
                    cellXfsE.SetInteger("count", FormattingRecords.Count);
                    cellXfsE.SetData(fonts.GetType(), fonts);
                    cellXfsE.SetData(formats.GetType(), formats);
                    cellXfsE.SetData(fills.GetType(), fills);
                    cellXfsE.SetData(borders.GetType(), borders);
                    foreach (FormattingRecord r in allStyleRecords)
                    {
                        cellXfsE.WriteElement(r);
                    }
                }
                if (parentStyles.Count > 0)
                {
                    using (WriteContext styleStyleXps = context.Write("cellStyles"))
                    {
                        int count = 0;
                        styleStyleXps.SetInteger("count", parentStyles.Count);
                        foreach (StyleFormattingRecord sr in parentStyles)
                        {
                            styleStyleXps.WriteElement(sr.Style);
                        }
                    }
                }

                var difTable = context.GetData<WriteObjectTable<DifferentialStyleRecord>>();
                context.SetData(difTable.GetType(), difTable);
                foreach (
                    DifferentialStyleRecord differentialStyleRecord in
                        Enumerable.Where(getDifferentialStyleRecords(), rr => rr != null))
                {
                    difTable.Add(differentialStyleRecord);
                }
                /*foreach (StandardConditionalFormattingRule rule in workbook.StandardRules)
                {
                    difTable.Add(rule.DifferentialStyleRecord);
                }
                foreach(var tableStyle in tableStyles)
                {
                    foreach(var t in tableStyle.Elements)
                    {
                        if (t.StyleRecord == null) continue;
                        difTable.Add(t.StyleRecord);
                    }
                }*/
                if (difTable.Count > 0)
                {
                    using (WriteContext c2 = c.Write("dxfs"))
                    {
                        foreach (DifferentialStyleRecord r in difTable)
                            c2.WriteElement(r);
                    }
                }
                if (TableStyles.Count > 0) //\\ missing default style
                {
                    using (WriteContext c2 = c.Write("tableStyles"))
                    {
                        c2.SetInteger("count", TableStyles.Count);
                        foreach (TableStyle tableStyle in TableStyles)
                            c2.WriteElement(tableStyle);
                    }
                }
                if (IndexedColors.Count > 0)
                {
                    using (WriteContext colorContext = c.Write("colors"))
                    {
                        using (WriteContext indexecColorsContext = colorContext.Write("indexedColors"))
                        {
                            foreach (Color indexedColor in IndexedColors)
                            {
                                writeRgbColor(indexecColorsContext, indexedColor);
                            }
                        }
                    }
                }
                c.WriteOptionalElement(Extension);
            }
        }

        #endregion

        private static IEnumerable<CellFormattingRecord> getDefaultStyleRecords()
        {
            //\\ yield return new StyleRecord(this);
            foreach (Fill fill in getDefaultFills())
            {
                var r = new CellFormattingRecord {Background = fill};
                yield return r;
            }
        }

        private static IEnumerable<Fill> getDefaultFills()
        {
            Fill f = new PatternFill(null, null, PatternType.None);
            yield return f;

            f = new PatternFill (null, null, PatternType.Gray125);
            yield return f;
        }

        internal Format getFormat(int i)
        {
            Format result = _numberFormats.ContainsKey(i) ? _numberFormats[i] : StandardFormats.GetFormat(i);
            Contract.Assert(result != null);
            return result;
        }

        public Color GetIndexedColor(int i)
        {
            if (IndexedColors.Count > i)
            {
                Color result = IndexedColors[i];
                //\\\Debug.WriteLine("returning " + result);
                return result;
            }
            return StandardPalette.GetColor(i);
        }

        private static int compareKeys<T>(KeyValuePair<T, int> a, KeyValuePair<T, int> b)
        {
            return a.Value.CompareTo(b.Value);
        }

        internal void ReadStyleSheet(RelatedReadContext ccc, PackagePart styleSheetPart)
        {
            using (Stream stream = styleSheetPart.GetStream())
            {
                using (var xr = new XmlTextReader(stream))
                {
                    var ctx = new ReadContext(xr, styleSheetPart, SpreadsheetConstants.SpreadsheetNamespaceUri);
                    _workbook.AddToReadContext(ctx);
                    readColors(ctx);
                }
            }
            ccc.Reset();
            using (ReadContext ctx = ccc)

                //using (Stream stream = styleSheetPart.GetStream())
            {
                //  using (var xr = new XmlTextReader(stream))
                {
                    //    var ctx = new ReadContext(xr, styleSheetPart, SpreadsheetConstants.SpreadsheetNamespaceUri);
                    //  workbook.AddToReadContext(ctx);
                    readXml(ctx);
                }
            }
        }

        private void readColors(ReadContext context)
        {
            using (ReadContext c = context.Read(xmlName))
            {
                c.PassAttributes();
                _numberFormats.Clear();
                Initialize();
                c.Eat("numFmts");
                c.Eat("fonts");
                c.Eat("fills");
                c.Eat("borders");
                c.Eat("cellStyleXfs");
                c.Eat("cellXfs");
                c.Eat("cellStyles");
                c.Eat("dxfs");
                c.Eat("tableStyles");
                if (c.ReaderLocalName == "colors")
                {
                    using (ReadContext ccc = c.Read("colors"))
                    {
                        _themeColors = new List<Color>();
                        if (ccc.ReaderLocalName == "themeColors")
                        {
                            using (ReadContext cThemeColors = ccc.Read("themeColors"))
                            {
                                while (cThemeColors.ReaderLocalName == "rgbColor")
                                {
                                    _themeColors.Add(readColor(cThemeColors));
                                }
                            }
                        }
                        _indexedColors.Clear();
                        if (ccc.ReaderLocalName == "indexedColors")
                        {
                            using (ReadContext cIndexColors = ccc.Read("indexedColors"))
                            {
                                while (cIndexColors.ReaderLocalName == "rgbColor")
                                {
                                    IndexedColors.Add(readColor(cIndexColors));
                                }
                            }
                        }
                        ccc.EatForNow("mruColors");
                    }
                }
                c.Eat("extLst");
            }
        }

        private static Color readColor(ReadContext cIndexColors)
        {
            using (ReadContext ccccc = cIndexColors.Read("rgbColor"))
            {
                var color = (Color) ColorConverter.ConvertFromString(@"#" + ccccc.GetString("rgb"));
                color.A = 255;
                return color;
            }
        }

        private static void writeRgbColor(WriteContext cIndexColors, Color c)
        {
            using (WriteContext ccccc = cIndexColors.Write("rgbColor"))
            {
                string rgb = c.A.ToString("X2") + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
                ccccc.SetString("rgb", rgb);
            }
        }

        private void readXml(ReadContext context)
        {
            IOfficeXmlSerializable s = this;
            s.ReadXml(context);
        }

        private IEnumerable<DifferentialStyleRecord> getDifferentialStyleRecords()
        {
            foreach (StandardConditionalFormattingRule rule in _workbook.StandardRules)
            {
                yield return rule.DifferentialStyleRecord;
            }
            foreach (TableStyle tableStyle in _tableStyles)
            {
                foreach (TableStyleElement t in tableStyle.Elements)
                {
                    yield return (t.StyleRecord);
                }
            }
            foreach (
                PivotTableDefinition pivotTable in
                    Enumerable.Where(
                        Enumerable.Select(Enumerable.OfType<Worksheet>(_workbook.Sheets), ws => ws.View.PivotTable),
                        t => t != null))
            {
                foreach (PivotTableFormat format in pivotTable.Formats)
                {
                    yield return format.DifferentialStyleRecord;
                }
            }

            foreach (
                Table table in Enumerable.SelectMany(Enumerable.OfType<Worksheet>(_workbook.Sheets), ws => ws.Tables))
            {
                yield return table.DataDifferentialStyleRecord;
                yield return table.HeaderRowBorderDataDifferentialStyleRecord;
                yield return table.HeaderRowDifferentialStyleRecord;
                yield return table.TotalsRowDataDifferentialStyleRecord;
                yield return table.TableBorderDataDifferentialStyleRecord;
                yield return table.TotalsRowBorderDataDifferentialStyleRecord;
            }
            foreach (
                TableColumn column in
                    Enumerable.SelectMany(
                        Enumerable.SelectMany(Enumerable.OfType<Worksheet>(_workbook.Sheets), ws => ws.Tables),
                        tt => tt.Columns))
            {
                yield return column.HeaderRowDifferentialStyleRecord;
                yield return column.DataDifferentialStyleRecord;
                yield return column.TotalsRowDiffertialStyleRecord;
            }
            foreach (
                CustomSheetView customSheetView in
                    Enumerable.SelectMany(_workbook.Sheets, sh => sh.GetCustomSheetViews()))
            {
                AutoFilter autoFilder = customSheetView.AutoFilter;
                if (autoFilder == null)
                    continue;
                foreach (FilterColumn column in autoFilder.FilterColumns)
                {
                    if (column.Filter is ColorFilter)
                        yield return ((ColorFilter) column.Filter).DifferentialStyleRecord;
                }
            }
        }

        internal FormattingRecord AddStyleRecord(FormattingRecord styleRecord)
        {
            Contract.Requires(styleRecord != null);
#if DEBUG
            if (styleRecord is StyleFormattingRecord)
            {
                Contract.Assert(((StyleFormattingRecord)styleRecord).Style.Owner == _workbook);
                Contract.Assert(!((StyleFormattingRecord)styleRecord).Style.IsBuiltIn);
            }
            if (FormattingRecords.Contains(styleRecord))
            {
                var oldRecord = FormattingRecords[styleRecord];
                Debug.WriteLine(oldRecord.Id);
                Debug.WriteLine(styleRecord.Id);
            }
#endif
            if (FormattingRecords.Contains(styleRecord))
                return FormattingRecords[styleRecord];
            Contract.Assert(!(FormattingRecords.Contains(styleRecord)));
            FormattingRecords.TryAdd(styleRecord);
            return null;
        }

        internal StyleFormattingRecord LookupNewStyleFormattingRecord(StyleFormattingRecord sr)
        {
            FormattingRecords.TryAdd(sr);
            return (StyleFormattingRecord) FormattingRecords[sr];
        }

        internal CellFormattingRecord LookupNewCellFormattingRecord(CellFormattingRecord sr)
        {
            FormattingRecords.TryAdd(sr);
            return (CellFormattingRecord) FormattingRecords[sr];
        }

        internal bool ContainsRecord(FormattingRecord value)
        {
            return FormattingRecords.Contains(value);
        }

        public void AddBuiltInStyle(CellStyle cellStyle)
        {
            if (_builtInStyles != null && cellStyle.IsBuiltIn)
            {
                int i = -1;
                foreach (CellStyle cs in _builtInStyles)
                {
                    i++;
                    if (cs.BuiltInId == cellStyle.BuiltInId)
                        break;
                }
                if (i >= 0)
                {
                    _builtInStyles.RemoveAt(i);
                    _builtInStyles.Insert(i, cellStyle);
                }
            }
        }
    }
}